www.gusucode.com > VC++ 实现类似Winrar一样带有图标的右键菜单-源码程序 > VC++ 实现类似Winrar一样带有图标的右键菜单-源码程序/code/IconExtract/IconExtractObj.cpp

    //Download by http://www.NewXing.com

// IconExtractObj.cpp : Implementation of CIconExtractObj
#include "stdafx.h"
#include "IconExtract.h"
#include "IconExtractObj.h"

/////////////////////////////////////////////////////////////////////////////
// CIconExtractObj

// IShellExtInit
HRESULT CIconExtractObj::Initialize(LPCITEMIDLIST pidlFolder, LPDATAOBJECT pDataObj, HKEY hProgID)
{
	FORMATETC fmt = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
	STGMEDIUM stg = { TYMED_HGLOBAL };
	HDROP hDrop;
    // Look for CF_HDROP data in the data object.
    if(FAILED(pDataObj->GetData(&fmt, &stg)))
	{
        // Nope! Return an "invalid argument" error back to Explorer.
        return E_INVALIDARG;
	}
    // Get a pointer to the actual data.
    hDrop = (HDROP)GlobalLock(stg.hGlobal);
    // Make sure it worked.
    if(NULL == hDrop)
	{
        return E_INVALIDARG;
	}
	// Sanity check, make sure there is at least one filename.
	UINT uNumFiles = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0);
    if(0 == uNumFiles)
	{
        GlobalUnlock(stg.hGlobal);
        ReleaseStgMedium (&stg);
        return E_INVALIDARG;
	}
	HRESULT hr = S_OK;
    // Get the name of the first file and store it in our member variable m_szFile.
    if(0 == DragQueryFile(hDrop, 0, m_szFile, MAX_PATH))
        hr = E_INVALIDARG;
	GlobalUnlock(stg.hGlobal);
    ReleaseStgMedium(&stg);
	return hr;
}

// IContextMenu
HRESULT CIconExtractObj::QueryContextMenu(HMENU hmenu, UINT uMenuIndex, UINT uCmdID, UINT uidLastCmd, UINT uFlags)
{
	//If the flags include CMF_DEFAULTONLY then we shouldn't do anything.
	if(uFlags & CMF_DEFAULTONLY)
		return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 0);
	int nMenus = 0;
	//The number of icons in the file
	int nIcons = (int)ExtractIconEx(m_szFile, -1, NULL, NULL, 0);
	if(nIcons > 0)
	{
		InsertMenu(hmenu, uMenuIndex, MF_STRING | MF_BYPOSITION, uCmdID++, _T("Extract &Large Icon"));
		if(NULL != m_hExtractBmpL)
			SetMenuItemBitmaps(hmenu, uMenuIndex, MF_BYPOSITION, m_hExtractBmpL, NULL);
		uMenuIndex++;

		InsertMenu(hmenu, uMenuIndex, MF_STRING | MF_BYPOSITION, uCmdID++, _T("Extract &Small Icon"));

		if(NULL != m_hExtractBmpS)
			SetMenuItemBitmaps(hmenu, uMenuIndex, MF_BYPOSITION, m_hExtractBmpS, NULL);
		uMenuIndex++;
		nMenus = 2;
    }
	return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, nMenus);
}

HRESULT CIconExtractObj::GetCommandString(UINT idCmd, UINT uFlags, UINT* pwReserved, LPSTR pszName, UINT cchMax)
{
	USES_CONVERSION;
	// Check idCmd, it must be 0 or 1 since we have two menu items
	if(idCmd > 1)
		return E_INVALIDARG;
	LPCTSTR szPrompt;
	if(uFlags & GCS_HELPTEXT)
	{
		switch(idCmd)
		{
			case 0:
				szPrompt = _T("Icon Extractor, Extracting the Large Icon");
				break;

            case 1:
				szPrompt = _T("Icon Extractor, Extracting the Small Icon");
				break;

			default:
				return E_INVALIDARG;
				break;
		}
		if(uFlags & GCS_UNICODE)
		{
			// We need to cast pszName to a Unicode string, and then use the Unicode string copy API.
			lstrcpynW((LPWSTR)pszName, T2CW(szPrompt), cchMax);
		}
		else
		{
			// Use the ANSI string copy API to return the help string.
			lstrcpynA(pszName, T2CA(szPrompt), cchMax);
		}
		return S_OK;
	}
	return E_INVALIDARG;
}

HRESULT CIconExtractObj::InvokeCommand(LPCMINVOKECOMMANDINFO pCmdInfo)
{
    // If lpVerb really points to a string, ignore this function call and bail out
    if(0 != HIWORD( pCmdInfo->lpVerb))
        return E_INVALIDARG;
	//Extract first icon
	HICON hIconLarge, hIconSmall;
	ExtractIconEx(m_szFile, 0, &hIconLarge, &hIconSmall, 1);
	ICONINFO oIconInfo;
	switch(LOWORD(pCmdInfo->lpVerb))
	{
		case 0:
			GetIconInfo(hIconLarge, &oIconInfo);
			break;

		case 1:
			GetIconInfo(hIconSmall, &oIconInfo);
			break;

		default:
			return E_INVALIDARG;
	}
	BOOL bOpen = ::OpenClipboard(NULL);
	if(TRUE==bOpen)
	{
		::EmptyClipboard();
		::SetClipboardData(CF_BITMAP, oIconInfo.hbmColor);
		::CloseClipboard();
	}
	//Destroy the icons
	DestroyIcon(hIconLarge);
	DestroyIcon(hIconSmall);
	return S_OK;
}